iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Modern Web

Dive into CSS Challenge:從問題到解決方案的實踐之旅系列 第 27

Day 27 - CSS Challenge #14:Flip Card(下)

  • 分享至 

  • xImage
  •  

題目

CSS Challenge Day14

  • 腳踏車卡片
    https://ithelp.ithome.com.tw/upload/images/20241006/2016940326edkkGqNJ.png

題目除了第一面的腳踏車卡片,還有滑鼠指上後的直升機卡片

  • 直升機卡片

https://ithelp.ithome.com.tw/upload/images/20241006/20169403WBPLRaRnlx.png

上面的圖是題目,而我們要做出幾乎一樣的樣子,題目中還有附上出題官方的CodePen,也有附上給我們解題用的template,當我們真的不會的時候,還是可以參考他們的寫法,所以沒有想像中困難。

我做好的此題CSS Challeage解答

那麼我們就開始吧。

前情提要

我們昨天已經把卡片翻轉跟腳踏車的動畫及樣式都做好了
https://ithelp.ithome.com.tw/upload/images/20241006/201694038XqNyfaX4D.png

那我們今天就來把剩下的繼續做完。

題目分析

這個題目要求我們製作一個滑鼠指上後會翻轉的卡片,大概列出項目如下:

  1. 正面卡片:腳踏車圖案
    • 地板移動的動畫
  2. 背面卡片:直升機圖案
    • 雲朵移動的動畫
  3. 滑鼠指上時卡片翻轉的動畫
    • 卡片需有3D視角

HTML Preprocessor

https://ithelp.ithome.com.tw/upload/images/20240926/20169403ODPOGkkVeM.png

因為我並不想要放好幾個一樣的 div 在裡面,所以在這裡我跟題目一樣使用了 slim 版本的 HTML 預處理器來寫。

Slim 是一個輕量化的模板語言,它使用縮排來結構化 HTML,簡化了標籤的書寫,不需要閉合標籤,並減少了重複的代碼。這樣可以讓 HTML 更加簡潔易讀,常用於像 Ruby on Rails 這樣的框架中。

例如,傳統 HTML 的寫法:

<div class="container">
  <h1>Hello World</h1>
</div>

在 Slim 中可以這樣寫:

.container
  h1 Hello World

這種語法可以大幅減少 HTML 的冗餘,使模板更易維護。

開始解題

直升機

.helicopter
    img src="https://100dayscss.com/codepen/helicopter.svg"
    .sky
        - for i in (1..9)
          div class="cloud-#{i}"

先在直升機區塊內放入官方提供的 svg 檔。
接著用一個 .sky 把雲朵移動樣子的動畫都包起來。
然後使用迴圈來寫 cloud-1cloud-9 總共 9 個 div

直升機的顛簸動畫

看題目可以知道,直升機飛行的時候有一點點上下顛簸的感覺,就像真的飛在空中不太穩的樣子,我們就先來做這個動畫

@keyframes animate-helicopter {
	0%, 100% {
		transform: translate3d(0,-5px,0);
	}
	50% {
		transform: translate3d(0,5px,0);
	}
}
  • @keyframes animate-helicopter:定義了一個名為 animate-helicopter 的動畫,用來控制元素的垂直縮放效果。
  • 0%, 100%translate3d(0,-5px,0) 表示直升機在 Y 軸上保持在 -5px 的位置。
  • 50%translate3d(0,5px,0) 在動畫中途 (50%)的時候,將直升機向下移動到 5px 的位置。

這樣直升機看起來就會在畫面上進行上下浮動的動作,製造出懸浮感。
動畫作好之後,我們來設定在直升機上。

.helicopter {
	z-index: 1;
	transform: rotateX(180deg);
		
	img {
		top: 57px;
		animation: animate-helicopter 1.5s ease-in-out infinite;
	}
}
  • .helicopter
    • z-index: 1:將 .helicopter 放置在第一層,因為我們昨天把腳踏車設定在 z-index: 2 把直升機蓋住,這邊要記得把直升機也設定一下。
    • transform: rotateX(180deg):沿 X 軸進行 180 度旋轉,這樣圖片看起來是上下顛倒的。
  • img (直升機 svg 圖像):
    • top: 57px:將圖片向下移動 57px。
    • animation: animate-helicopter .6s ease-in-out infinite
      • 對圖片應用名為 animate-helicopter 的動畫。
      • 1.5s:動畫持續時間為 1.5 秒。
      • ease-in-out:動畫速度曲線,表示動畫以較慢的速度開始和結束,中間速度較快。
      • infinite:動畫無限次重複,形成循環效果。

https://ithelp.ithome.com.tw/upload/images/20241006/20169403uAwnHgOLBp.png

雲朵移動的動畫

.helicopter {
    ...
    .sky {
		position: absolute;
		top: 0;
		left: 80px;
		bottom: 0;
		width: 160px;
		overflow: hidden;
    }
}

先來設定雲朵的所會出現的位置。

  • position: absolute:設定絕對定位,讓它可以依據父項 helicopter 作定位。
  • top: 0 left: 80px bottom: 0:控制 .sky 在直升機區塊內的定位,將其從上到下填滿並從左邊偏移 80 像素。
  • width: 160px:設定 .sky 的寬度為 160 像素,這是容納內部雲朵的區域。
  • overflow: hidden:隱藏超出這個區域的內容,晚點我們會在 .sky 上面套用昨天做好的位移動畫 animate-speed,位移到超出這個範圍的就會被隱藏。

再來就是設定 @for 迴圈中雲朵的線條:

.sky {
    ...
    @for $i from 1 through 9 {
        .cloud-#{$i} {
			position: absolute;
			right: -25px;
			top: (20 + $i * 14) + px;
			height: 3px;
			width: (10 + random(150) / 10) + px;
			background: $gray;
			border-radius: 3px;
			animation: animate-speed (0.6 + random(2) / 10) + s
                       linear (random(10) / 10) + s infinite;
		}
	}
}

這段程式碼的詳細解說如下:
@for $i from 1 through 9:使用 @for 循環語法,會根據 $i 生成 9 個 .cloud 元素,並給每個元素動態分配不同的屬性。

  • 位置與大小:

    • position: absolute:每個 .cloud 元素的定位方式是絕對定位,根據父元素 .sky 的相對位置來決定。
    • right: -25px:設定每條線條距離父元素的右邊界 25px。
    • top: (20 + $i * 14) + px:根據迴圈索引 $i 動態調整每個雲的垂直位置,確保它們間隔均勻排列。20 是初始高度,$i * 14 為每個雲朵增加 14px 的距離。
    • height: 3px :高度設定固定為 3px,。
    • width: (10 + random(150) / 10) + px:寬度根據 random(150) 函數隨機產生的值決定,讓每個雲的大小都不同。
      • random(150) 會產生一個 0 到 150 之間的隨機整數。
      • random(150) / 10 將這個隨機數值除以 10,因此隨機寬度在 0 到 15 之間。
      • 再加上 10,讓每個元素的寬度範圍變成 10 到 25px。
  • 背景樣式:

    • background: $gray:讓每條線有灰色的底色。
  • 圓角效果:

    • border-radius: 3px:設定線條兩端的圓角效果。
  • 動畫效果:

    • animate-speed:每個 .cloud 會根據這個動畫來移動。
    • (0.6 + random(2) / 10) + s:定義動畫持續時間從 0.6 秒開始,random(2) 生成一個 0 到 2 之間的隨機數,再除以10,讓每條線的動畫時間不同(約為0.8秒到1秒左右),讓每朵雲的移動速度稍有差異。
    • linear:動畫以等速運行,沒有加速度或減速度的效果。
    • (random(10) / 10) + s:設置隨機延遲,讓每個雲的動畫開始時間不同,避免它們同時移動。
    • infinite:動畫會無限次重複執行,使雲朵不斷移動。

剛做好的時候就長這樣
https://ithelp.ithome.com.tw/upload/images/20241006/20169403BhhPKICBUQ.png

那這樣就做完這一題囉。


Wrap up and go home

希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。

那今天就先到這裡,明天我們再繼續來玩下一集。


上一篇
Day 26 - CSS Challenge #14:Flip Card(上)
下一篇
Day 28 - CSS Challenge #15:Upload File via Antd (上)
系列文
Dive into CSS Challenge:從問題到解決方案的實踐之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言